package com.zone.gateway.assist.config;

import com.zone.gateway.assist.domain.service.GatewayCenterService;
import com.zone.gateway.assist.listener.GatewayListener;
import com.zone.gateway.assist.listener.RedisMessageRpcRegisterListener;
import com.zone.gateway.common.Constant;
import com.zone.gateway.core.session.GatewaySessionFactory;
import com.zone.gateway.core.session.impl.DefaultGatewaySessionFactory;
import com.zone.gateway.core.socket.SessionServer;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

/**
 * @author: zongzi
 * @description: TODO
 * @date: 2025/4/24
 */
@Configuration
@EnableConfigurationProperties(ApiGatewayProperties.class)
public class ApiGatewayAssistConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(ApiGatewayAssistConfiguration.class);
    private final ApiGatewayProperties properties;

    public ApiGatewayAssistConfiguration(ApiGatewayProperties properties) {
        this.properties = properties;
    }

    @Bean
    public GatewayCenterService apiGatewayRegisterService() {
        return new GatewayCenterService();
    }

    @Bean
    @DependsOn({"configuration", "serverChannel"})
    public GatewayListener gatewayListener(GatewayCenterService apiGatewayRegisterService, com.zone.gateway.core.session.Configuration configuration, Channel serverChannel) {
        return new GatewayListener(properties, apiGatewayRegisterService, configuration, serverChannel);
    }

    @Bean
    public com.zone.gateway.core.session.Configuration configuration() {
        return new com.zone.gateway.core.session.Configuration();
    }

    @Bean
    @DependsOn("configuration")
    public Channel serverChannel(com.zone.gateway.core.session.Configuration configuration) {
        try {
            logger.info("Initializing Netty server with configuration: {}", configuration);
            GatewaySessionFactory gatewaySessionFactory = new DefaultGatewaySessionFactory(configuration);
            SessionServer sessionServer = new SessionServer(gatewaySessionFactory, configuration);
            Channel channel = sessionServer.bind();
            logger.info("Netty server initialized successfully");
            return channel;
        } catch (Exception e) {
            logger.error("Failed to initialize Netty server", e);
            throw new RuntimeException("Failed to initialize Netty server", e);
        }
    }

    @Bean
    @DependsOn({"gatewayListener", "apiGatewayRegisterService"})
    public RedisMessageRpcRegisterListener redisMessageRpcRegisterListener(GatewayListener gatewayListener, GatewayCenterService apiGatewayRegisterService) {
        return new RedisMessageRpcRegisterListener(gatewayListener, apiGatewayRegisterService, properties);
    }

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        // 创建 Redis 连接配置
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName("localhost");  // Redis 服务器地址
        config.setPort(16379);            // Redis 端口
        config.setDatabase(0);           // 使用的数据库索引

        // 创建连接工厂
        LettuceConnectionFactory factory = new LettuceConnectionFactory(config);
        factory.afterPropertiesSet();    // 初始化连接工厂

        return factory;
    }

    @Bean
    @DependsOn({"redisMessageRpcRegisterListener", "redisConnectionFactory"})
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisMessageRpcRegisterListener redisMessageRpcRegisterListener, RedisConnectionFactory redisConnectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(redisConnectionFactory);

        // 订阅频道
        container.addMessageListener(redisMessageRpcRegisterListener,
                new ChannelTopic(Constant.RPC_REGISTER_CHANNEL));

        return container;
    }
}
